#include "server_user.h"

uint8    server_user_list_load_flag; // 用户信息列表加载成功标志

UserList server_user_list;  // 用户信息链表

/* 根据ID查找y用户
    * 该函数用于根据用户ID查找用户信息
    * @param id 用户ID
    * @return 返回找到的用户节点指针，如果未找到或出现异常则返回NULL
*/
UserNode *  server_find_user_by_id(uint32 id){
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return NULL; // 未加载用户信息列表
    }
    // 检查用户数量是否为0
    if (server_user_list.count == 0) {
        server_log(LOG_SYSTEM, "No users in the list. User find function return NULL.");
        return NULL; // 返回空结果
    }
    // 遍历用户列表查找指定ID的用户
    UserNode * current_node = server_user_list.first_node;
    while(current_node != NULL) {
        if (current_node->user.id == id) {
            // 找到用户
            return current_node;
        }
        current_node = current_node->next; // 移动到下一个节点
    }
    // 未找到用户
    server_log(LOG_SYSTEM, "User with ID %u not found.", id);
    return NULL; // 返回空结果
}

/* 根据名称查找用户
    * 该函数用于根据用户名称查找用户信息
    * @param name 用户名称
    * @param is_sensitive 是否大小写敏感
    * @return 返回找到的用户节点指针，如果未找到或出现异常则返回NULL
*/
UserPtrList *  server_find_user_by_name(wchar_t * name, StringIsSensitive is_sensitive) {
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return NULL; // 未加载用户信息列表
    }
    // 检查用户数量是否为0
    if (server_user_list.count == 0) {
        server_log(LOG_SYSTEM, "No users in the list. User find function return NULL.");
        return NULL; // 返回空结果
    }
    // 遍历用户列表查找指定名称的用户
    // 创建返回的用户链表
    UserNode    * current_node  = server_user_list.first_node;
    UserPtrList * result_list   = (UserPtrList *)malloc(sizeof(UserPtrList)); // 结果链表，存储匹配的用户结构体指针信息
    if (result_list == NULL) {
        server_log(LOG_SYSTEM, "Failed to allocate memory for user pointer list.");
        return NULL; // 内存分配失败，返回NULL
    }
    result_list->first_node = NULL; // 初始化结果链表头指针
    result_list->last_node  = NULL; // 初始化结果链表尾指针
    result_list->count      = 0;    // 初始化结果链表计数为0
    while(current_node != NULL) {
        // 根据大小写敏感性比较名称
        if (server_string_is_in(current_node->user.name, name, is_sensitive)){
            UserPtrNode * new_node = malloc(sizeof(UserPtrNode)); // 找到符合条件的用户，创建新节点
            if (new_node == NULL) {
                server_log(LOG_SYSTEM, "Failed to allocate memory for user pointer node.");
                free(result_list); // 释放已分配的结果链表内存
                server_assert(new_node == NULL); // 重大错误，断言
                return NULL; // 内存分配失败，返回NULL
            }
            new_node->user = &(current_node->user); // 将用户结构体指针赋值给新节点
            new_node->next = NULL; // 新节点的next指针初始化为NULL
            new_node->prev = result_list->last_node; // 设置新节点的prev指针为当前结果链表的尾节点
            if (result_list->last_node != NULL) {
                result_list->last_node->next = new_node; // 如果结果链表不为空，设置尾节点的next指针
            } else {
                result_list->first_node = new_node; // 如果结果链表为空，设置头指针
            }
            result_list->last_node = new_node; // 更新结果链表的尾指针
            result_list->count++; // 增加结果链表计数
        }
        current_node = current_node->next; // 移动到下一个节点
    }
    if (result_list->count == 0) {
        server_log(LOG_SYSTEM, "No users found with the name '%ls'.", name);
        free(result_list); // 如果没有找到用户，释放结果链表内存
        return NULL; // 返回NULL表示未找到用户
    }
    server_log(LOG_SYSTEM, "Found %u users with the name '%ls'.", result_list->count, name);
    return result_list; // 返回找到的用户列表
}

/* 添加用户
    * 该函数用于添加新的用户到用户信息列表中
    * @param user 用户信息结构体指针，不采用其中的ID，因为ID是唯一的，且由服务器自动分配
    * @return 如果添加成功返回0，失败返回1
*/
uint8       server_add_user(User * user){
    // 先检查user是否为NULL
    if (user == NULL) {
        server_log(LOG_SYSTEM, "Cannot add user because the user pointer is NULL.");
        server_assert(user == NULL); // 重大错误，断言
        return 1; // 返回1表示添加失败
    }
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return 1; // 未加载用户信息列表，返回1
    }
    // 创建新的用户节点
    UserNode * new_node = malloc(sizeof(UserNode));
    if (new_node == NULL) {
        server_log(LOG_SYSTEM, "Memory allocation failed while creating user node.");
        server_assert(new_node == NULL); // 重大错误，断言
        return 1; // 内存分配失败，返回1
    }
    user->id = book_config.next_user_id++; // 分配新的用户ID

    new_node->user = *user; // 复制用户信息到新节点
    new_node->next = NULL; // 初始化新节点的next指针
    new_node->prev = server_user_list.last_node; // 设置前驱节点

    // 将新节点添加到链表中
    if (server_user_list.last_node != NULL) {
        server_user_list.last_node->next = new_node; // 如果不是第一个节点，设置前驱节点的next指针
    } else {
        server_user_list.first_node = new_node; // 如果是第一个节点，设置头指针
    }
    server_user_list.last_node = new_node; // 更新尾指针
    server_user_list.count++; // 增加用户数量

    server_log(LOG_SYSTEM, "User with ID %u added successfully.", user->id);
    return 0; // 成功添加用户，返回0
}

/*  删除用户
    * 该函数用于删除用户信息列表中的指定用户节点
    * @param user_node 要删除的用户节点指针
    * @return 如果删除成功返回0，未找到用户或异常返回1
*/
uint8       server_delete_user(UserNode * user_node){
    // 检查用户节点是否为NULL
    if (user_node == NULL) {
        server_log(LOG_SYSTEM, "Cannot delete user because the user_node pointer is NULL.");
        return 1; // 返回1表示删除失败
    }
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return 1; // 未加载用户信息列表，返回1
    }
    // 删除用户节点
    if (user_node == server_user_list.first_node) { // 如果是头节点
        server_user_list.first_node = user_node->next; // 更新头指针
        if (user_node->next != NULL) {
            user_node->next->prev = NULL; // 设置下一个节点的prev指针为NULL
        } else {
            server_user_list.last_node = NULL; // 如果是最后一个节点，更新尾指针
        }
    } else {
        user_node->prev->next = user_node->next; // 设置前驱节点的next指针
        if (user_node->next != NULL) {
            user_node->next->prev = user_node->prev; // 设置下一个节点的prev指针
        } else {
            server_user_list.last_node = user_node->prev; // 如果是最后一个节点，更新尾指针
        }
    }
    // 释放用户节点内存
    free(user_node);
    server_user_list.count--; // 减少用户数量

    server_log(LOG_SYSTEM, "User deleted successfully.");
    return 0; // 成功删除用户，返回0
}

/*  根据ID删除用户
    * 该函数用于根据用户ID删除用户信息列表中的指定用户
    * @param id 用户ID
    * @return 如果删除成功返回0，未找到用户或异常返回1
*/
uint8       server_delete_user_by_id(uint32 id){
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return 1; // 未加载用户信息列表，返回1
    }
    // 查找用户节点
    UserNode * user_node = server_find_user_by_id(id);
    if (user_node == NULL) {
        server_log(LOG_SYSTEM, "User with ID %u not found.", id);
        return 1; // 未找到用户，返回1
    }
    // 删除用户节点
    server_log(LOG_SYSTEM, "User with ID %u deleted from user list.", id);
    return server_delete_user(user_node);
}

/* 修改用户信息
    * 该函数用于修改用户信息列表中的指定用户节点
    * @param user_node 要修改的用户节点指针
    * @param new_user 新的用户信息结构体指针，不使用其中的ID，保持原ID不变
    * @return 如果修改成功返回0，未找到用户或异常返回1
*/
uint8       server_modify_user(UserNode * user_node, User * new_user_info){
    if (user_node == NULL || new_user_info == NULL) {
        server_log(LOG_SYSTEM, "Cannot modify user because user_node or new_user pointer is NULL.");
        return 1; // 返回1表示修改失败
    }
    // 保持ID不变，修改其他信息
    uint32 id = user_node->user.id; // 保存原ID
    user_node->user = *new_user_info; // 复制新的用户信息到节点
    user_node->user.id = id; // 恢复原ID
    server_log(LOG_SYSTEM, "User with ID %u modified successfully.", user_node->user.id);
    return 0; // 成功修改用户，返回0
}

/* 用户登录
    * 该函数用于用户登录验证
    * @param user_id 用户ID
    * @param password 用户密码
    * @return 返回用户信息结构体指针，如果登录失败返回NULL
*/
UserFunctionReturn server_user_login(uint32 user_id, wchar_t * password, User * user_p){
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return USER_UNKNOWN_ERROR; // 未加载用户信息列表，返回失败
    }
    // 查找用户节点
    UserNode * user_node = server_find_user_by_id(user_id);
    if (user_node == NULL) {
        server_log(LOG_SYSTEM, "User with ID %u not found.", user_id);
        return USER_UNKNOWN_ERROR; // 未找到用户，返回用户未找到
    }
    // 验证密码
    if (wcscmp(user_node->user.password, password) != 0) {
        server_log(LOG_SYSTEM, "Password mismatch for user ID %u.", user_id);
        return LOGIN_PASSWORD_ERROR; // 密码不匹配，返回NULL
    }
    // 登录成功，将用户信息复制到输出参数
    if (user_p != NULL) {
        *user_p = user_node->user; // 复制用户信息到输出参数
    } else {
        server_log(LOG_SYSTEM, "User pointer is NULL, cannot return user information.");
        return USER_UNKNOWN_ERROR; // 输出参数为NULL，返回失败
    }
    server_log(LOG_SYSTEM, "User with ID %u logged in successfully.", user_id);
    return LOGIN_SUCCESS; // 返回成功
}

/* 加载用户信息列表
    * 该函数用于从文件中加载用户信息到链表
    * @return 如果加载成功返回0，失败或异常返回1
*/
uint8       server_load_user_list(void){
    server_log(LOG_SYSTEM, "Loading user list from user_data_file...");
    // 检查用户信息列表是否已加载
    if (server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list already loaded.");
        return 0; // 已加载，返回0
    }
    // 打开用户信息文件
    FILE * user_data_file = fopen(USER_DATA_FILE_PATH, "rb");
    if (user_data_file == NULL) {
        server_log(LOG_SYSTEM, "Failed to open user data file: %s", USER_DATA_FILE_PATH);
        return 1; // 打开文件失败，返回1
    }
    // 读取用户数据
    while (1) {
        User * user = malloc(sizeof(User));
        if (user == NULL) {
            server_log(LOG_SYSTEM, "Memory allocation failed while reading user data.");
            fclose(user_data_file);
            return 1; // 内存分配失败，返回1
        }
        size_t read_size = fread(user, sizeof(User), 1, user_data_file);
        if (read_size == 0) {
            free(user); // 如果读取失败或到达文件末尾，释放内存
            break; // 读取结束，退出循环
        }
        // 创建新的用户节点
        UserNode * new_node = malloc(sizeof(UserNode));
        if (new_node == NULL) {
            server_log(LOG_SYSTEM, "Memory allocation failed while creating user node.");
            free(user); // 释放用户结构体内存
            fclose(user_data_file);
            return 1; // 内存分配失败，返回1
        }
        new_node->user = *user; // 复制用户信息到新节点
        new_node->next = NULL; // 初始化新节点的next指针
        new_node->prev = server_user_list.last_node; // 设置前驱节点

        // 将新节点添加到链表中
        if (server_user_list.last_node != NULL) {
            server_user_list.last_node->next = new_node; // 如果不是第一个节点，设置前驱节点的next指针
        } else {
            server_user_list.first_node = new_node; // 如果是第一个节点，设置头指针
        }
        server_user_list.last_node = new_node; // 更新尾指针
        server_user_list.count++; // 增加用户数量

        free(user); // 释放用户数据内存
    }
    fclose(user_data_file);
    server_user_list_load_flag = 1; // 标记用户信息列表已加载
    server_log(LOG_SYSTEM, "User list loaded successfully.");
    return 0; // 成功加载用户信息，返回0
}

/* 保存用户信息列表
    * 该函数用于将用户信息列表保存到文件中
    * @return 如果保存成功返回0，失败或异常返回1
*/
uint8       server_save_user_list(void){
    server_log(LOG_SYSTEM, "Saving user list to user_data_file...");
    // 检查用户信息列表是否已加载
    if (!server_user_list_load_flag) {
        server_log(LOG_SYSTEM, "User info list not loaded yet.");
        server_assert(!server_user_list_load_flag); // 重大错误，断言
        return 1; // 未加载用户信息列表，返回1
    }
    // 打开用户数据文件
    FILE * user_data_file = fopen(USER_DATA_FILE_PATH, "wb");
    if (user_data_file == NULL) {
        server_log(LOG_SYSTEM, "Failed to open user data file for writing: %s", USER_DATA_FILE_PATH);
        return 1; // 打开文件失败，返回1
    }
    // 遍历用户链表并写入数据
    UserNode * current_node = server_user_list.first_node;
    while (current_node != NULL) {
        size_t write_size = fwrite(&(current_node->user), sizeof(User), 1, user_data_file);
        if (write_size != 1) {
            server_log(LOG_SYSTEM, "Failed to write user data to file.");
            fclose(user_data_file);
            return 1; // 写入失败，返回1
        }
        current_node = current_node->next; // 移动到下一个节点
    }
    fclose(user_data_file); // 关闭文件
    server_log(LOG_SYSTEM, "User list saved successfully. Total users: %u", server_user_list.count);
    return 0; // 成功保存用户信息，返回0
}
